`timescale 1ns / 1ps

`include "data_width.vh"

module rd_src_p_reorder_block_1 #(parameter
    VERTEX_BRAM_NUM     = `VERTEX_BRAM_NUM,
    VERTEX_BRAM_DWIDTH  = `VERTEX_BRAM_DWIDTH,
    REORDER_LOC_Y_WIDTH = `REORDER_LOC_Y_WIDTH,
    VERTEX_PIPE_NUM     = `VERTEX_PIPE_NUM,
    TOT_EDGE_MASK_WIDTH = `TOT_EDGE_MASK_WIDTH,
    TOT_ACC_ID_WIDTH    = `TOT_ACC_ID_WIDTH,
    DST_ID_DWIDTH       = `DST_ID_DWIDTH,
    VERTEX_MASK_WIDTH   = `VERTEX_MASK_WIDTH,
    DEGREE_DWIDTH       = `DEGREE_DWIDTH,
    EDGE_PIPE_NUM       = `EDGE_PIPE_NUM
    ) (
        input                                                   clk,
        input                                                   front_rst,
        input [VERTEX_BRAM_DWIDTH * VERTEX_BRAM_NUM - 1 : 0]    front_src_p,
        input [REORDER_LOC_Y_WIDTH * VERTEX_BRAM_NUM - 1 : 0]   front_reorder_loc_y,
        input [VERTEX_BRAM_NUM - 1 : 0]                         front_src_p_valid,
        input [DEGREE_DWIDTH * EDGE_PIPE_NUM - 1 : 0]           front_src_degree,
        input                                                   front_rd_src_p_addr_finish,
        input [TOT_EDGE_MASK_WIDTH - 1 : 0]                     front_tot_src_p_mask,
        input [TOT_ACC_ID_WIDTH - 1 : 0]                        front_tot_acc_id,
        input                                                   front_any_dst_data_valid,
        input [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]         front_dst_id,
        input [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]     front_src_p_mask_r,
        input [VERTEX_PIPE_NUM - 1 : 0]                         front_dst_data_valid,
        input                                                   back_stage_vertex_full,

        output                                                  rst,
        output                                                  buffer_full_vertex,
        output [VERTEX_BRAM_DWIDTH * VERTEX_BRAM_NUM - 1 : 0]   src_p,
        output [VERTEX_BRAM_NUM - 1 : 0]                        src_p_valid,
        output                                                  rd_src_p_addr_finish,
        output [DEGREE_DWIDTH * EDGE_PIPE_NUM - 1 : 0]          src_degree,
        output [TOT_EDGE_MASK_WIDTH - 1 : 0]                    tot_src_p_mask,
        output [TOT_ACC_ID_WIDTH - 1 : 0]                       tot_acc_id,
        output                                                  any_dst_data_valid,
        output [DST_ID_DWIDTH * VERTEX_PIPE_NUM - 1 : 0]        dst_id,
        output [VERTEX_MASK_WIDTH * VERTEX_PIPE_NUM - 1 : 0]    src_p_mask_r,
        output [VERTEX_PIPE_NUM - 1 : 0]                        dst_data_valid);
    
    wire                            mask_buffer_empty, mask_buffer_full;
    wire [VERTEX_PIPE_NUM - 1 : 0]  dst_buffer_empty, dst_buffer_full;
    wire [VERTEX_PIPE_NUM - 1 : 0]  data_valid;

    assign buffer_full_vertex = dst_buffer_full[0];
    assign any_dst_data_valid = data_valid[0];

    rd_src_p_reorder_block_1_para_trans P (
        .clk(clk), .front_rst(front_rst),

        .rst(rst));

    rd_src_p_reorder_block_1_edge E1 (
        .clk(clk), .rst(front_rst),
        .front_src_p(front_src_p), .front_reorder_loc_y(front_reorder_loc_y), .front_src_p_valid(front_src_p_valid),
        .front_src_degree(front_src_degree),
        .front_rd_src_p_addr_finish(front_rd_src_p_addr_finish),

        .src_p(src_p), .src_p_valid(src_p_valid),
        .src_degree(src_degree),
        .rd_src_p_addr_finish(rd_src_p_addr_finish));

    rd_src_p_reorder_block_1_mask M1 (
        .clk(clk), .rst(front_rst),
        .front_tot_src_p_mask(front_tot_src_p_mask), .front_tot_acc_id(front_tot_acc_id),
        .front_any_dst_data_valid(front_any_dst_data_valid), .back_stage_vertex_full(back_stage_vertex_full),

        .buffer_empty(mask_buffer_empty), .buffer_full(mask_buffer_full),
        .tot_src_p_mask(tot_src_p_mask), .tot_acc_id(tot_acc_id));

    generate
        genvar i;
        for (i = 0; i < VERTEX_PIPE_NUM; i = i + 1) begin : M11_1_BLOCK_1
            rd_src_p_reorder_block_1_vertex_single V (
                .clk                        (clk),
                .rst                        (front_rst),
                .front_dst_id               (front_dst_id[(i + 1) * DST_ID_DWIDTH - 1 : i * DST_ID_DWIDTH]),
                .front_src_p_mask_r         (front_src_p_mask_r[(i + 1) * VERTEX_MASK_WIDTH - 1 : i * VERTEX_MASK_WIDTH]),
                .front_dst_data_valid       (front_dst_data_valid[i]),
                .front_any_dst_data_valid   (front_any_dst_data_valid),
                .back_stage_vertex_full     (back_stage_vertex_full),

                .buffer_empty               (dst_buffer_empty[i]),
                .buffer_full                (dst_buffer_full[i]),
                .data_valid                 (data_valid[i]),
                .dst_id                     (dst_id[(i + 1) * DST_ID_DWIDTH - 1 : i * DST_ID_DWIDTH]),
                .src_p_mask_r               (src_p_mask_r[(i + 1) * VERTEX_MASK_WIDTH - 1 : i * VERTEX_MASK_WIDTH]),
                .dst_data_valid             (dst_data_valid[i]));
        end
    endgenerate

endmodule

module rd_src_p_reorder_block_1_para_trans (
    input       clk,
    input       front_rst,

    output reg  rst);

    always @ (posedge clk) begin
        rst <= front_rst;
    end

endmodule

// 将 k 个结果按 32 一组分区，每个分区分别进行 reorder
module rd_src_p_reorder_block_1_edge #(parameter
    REORDER_LOC_Y_WIDTH = `REORDER_LOC_Y_WIDTH,
    EDGE_PIPE_NUM = `EDGE_PIPE_NUM,
    VERTEX_BRAM_NUM = `VERTEX_BRAM_NUM,
    VERTEX_BRAM_DWIDTH = `VERTEX_BRAM_DWIDTH,
    DEGREE_DWIDTH       = `DEGREE_DWIDTH
    ) (
        input                                                   clk,
        input                                                   rst,
        input [VERTEX_BRAM_DWIDTH * VERTEX_BRAM_NUM - 1 : 0]    front_src_p,
        input [REORDER_LOC_Y_WIDTH * VERTEX_BRAM_NUM - 1 : 0]   front_reorder_loc_y,
        input [VERTEX_BRAM_NUM - 1 : 0]                         front_src_p_valid,
        input [DEGREE_DWIDTH * EDGE_PIPE_NUM - 1 : 0]           front_src_degree,
        input                                                   front_rd_src_p_addr_finish,
        input                                                   back_stage_edge_full,

        output [VERTEX_BRAM_DWIDTH * VERTEX_BRAM_NUM - 1 : 0]   src_p,
        output [VERTEX_BRAM_NUM - 1 : 0]                        src_p_valid,
        output reg [DEGREE_DWIDTH * EDGE_PIPE_NUM - 1 : 0]      src_degree,
        output reg                                              rd_src_p_addr_finish);

    always @ (posedge clk) begin
        if (rst) begin
            rd_src_p_addr_finish <= 1'b0;
            src_degree <= 0;
        end
        else begin
            rd_src_p_addr_finish <= front_rd_src_p_addr_finish;
            src_degree <= front_src_degree;
        end
    end

    generate
        genvar i;
        for (i = 0; i < VERTEX_BRAM_NUM / EDGE_PIPE_NUM; i = i + 1) begin: M11_1_BLOCK_2
            rd_src_p_reorder_block_1_edge_single ES (
                .clk(clk), .rst(rst),
                .front_src_p_single(front_src_p[(i + 1) * VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : i * VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM]),
                .front_reorder_loc_y_single(front_reorder_loc_y[(i + 1) * REORDER_LOC_Y_WIDTH * EDGE_PIPE_NUM - 1 : i * REORDER_LOC_Y_WIDTH * EDGE_PIPE_NUM]),
                .front_src_p_valid_single(front_src_p_valid[(i + 1) * EDGE_PIPE_NUM - 1 : i * EDGE_PIPE_NUM]),

                .src_p_single(src_p[(i + 1) * VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : i * VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM]),
                .src_p_valid_single(src_p_valid[(i + 1) * EDGE_PIPE_NUM - 1 : i * EDGE_PIPE_NUM]));
        end
    endgenerate

endmodule

// 对 32 个结果进行重排
module rd_src_p_reorder_block_1_edge_single #(parameter
    REORDER_LOC_Y_WIDTH = `REORDER_LOC_Y_WIDTH,
    EDGE_PIPE_NUM = `EDGE_PIPE_NUM,
    VERTEX_BRAM_NUM = `VERTEX_BRAM_NUM, VERTEX_BRAM_DWIDTH = `VERTEX_BRAM_DWIDTH
    ) (
        input                                               clk,
        input                                               rst,
        input [VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : 0]  front_src_p_single,
        input [REORDER_LOC_Y_WIDTH * EDGE_PIPE_NUM - 1 : 0] front_reorder_loc_y_single,
        input [EDGE_PIPE_NUM - 1 : 0]                       front_src_p_valid_single,

        output [VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : 0] src_p_single,
        output [EDGE_PIPE_NUM - 1 : 0]                      src_p_valid_single);
        
    generate
        genvar i;
        for (i = 0; i < EDGE_PIPE_NUM; i = i + 1) begin: M11_1_BLOCK_2
            rd_src_p_reorder_block_1_edge_single_single #(.LOC(i)) ESS (
                .clk(clk), .rst(rst),
                .front_src_p_single(front_src_p_single),
                .front_reorder_loc_y_single(front_reorder_loc_y_single),
                .front_src_p_valid_single(front_src_p_valid_single),

                .src_p_single(src_p_single[VERTEX_BRAM_DWIDTH * (i + 1) - 1 : VERTEX_BRAM_DWIDTH * i]), .src_p_valid_single(src_p_valid_single[i]));
        end
    endgenerate

endmodule

// 分 32 条流水线对 32 个结果进行重排
module rd_src_p_reorder_block_1_edge_single_single #(parameter
    LOC = 5'b00000,
    REORDER_LOC_Y_WIDTH = `REORDER_LOC_Y_WIDTH,
    EDGE_PIPE_NUM = `EDGE_PIPE_NUM,
    VERTEX_BRAM_NUM = `VERTEX_BRAM_NUM, VERTEX_BRAM_DWIDTH = `VERTEX_BRAM_DWIDTH
    ) (
        input                                               clk,
        input                                               rst,
        input [VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : 0]  front_src_p_single,
        input [REORDER_LOC_Y_WIDTH * EDGE_PIPE_NUM - 1 : 0] front_reorder_loc_y_single,
        input [EDGE_PIPE_NUM - 1 : 0]                       front_src_p_valid_single,

        output reg [VERTEX_BRAM_DWIDTH - 1 : 0]             src_p_single,
        output reg                                          src_p_valid_single);
        
    wire [EDGE_PIPE_NUM - 1 : 0] flag;
    
    // hold time < 0, so cancel local register.
    /*
    // 增加一层缓冲，先将数据存在本地，再计算输出
    reg [VERTEX_BRAM_DWIDTH * EDGE_PIPE_NUM - 1 : 0] src_p_single_reg;
    reg [REORDER_LOC_Y_WIDTH * EDGE_PIPE_NUM - 1 : 0] reorder_loc_y_single_reg;
    reg [EDGE_PIPE_NUM - 1 : 0] src_p_valid_single_reg;

    always @ (posedge clk) begin
        if (rst) begin
            src_p_single_reg <= 0;
            reorder_loc_y_single_reg <= 0;
            src_p_valid_single_reg <= 0;
        end
        else begin
            src_p_single_reg <= front_src_p_single;
            reorder_loc_y_single_reg <= front_reorder_loc_y_single;
            src_p_valid_single_reg <= front_src_p_valid_single;
        end
    end
    */

    generate
        genvar i;
        for (i = 0; i < EDGE_PIPE_NUM; i = i + 1) begin: M11_1_BLOCK_3
            assign flag[i] = (front_reorder_loc_y_single[(i + 1) * REORDER_LOC_Y_WIDTH - 1 : i * REORDER_LOC_Y_WIDTH] == LOC) && front_src_p_valid_single[i];
        end
    endgenerate

    always @ (posedge clk) begin
        if (rst) begin
            src_p_single <= 0;
            src_p_valid_single <= 1'b0;
        end
        else begin
            casex (flag)
                32'b00000000000000000000000000000000: begin
                    src_p_single <= 0;
                    src_p_valid_single <= 1'b0;
                end
                32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH - 1 : 0];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx10: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 2 - 1 : VERTEX_BRAM_DWIDTH];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxx100: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 3 - 1 : VERTEX_BRAM_DWIDTH * 2];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxx1000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 4 - 1 : VERTEX_BRAM_DWIDTH * 3];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxxxxxxxxx10000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 5 - 1 : VERTEX_BRAM_DWIDTH * 4];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxxxxxxxx100000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 6 - 1 : VERTEX_BRAM_DWIDTH * 5];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxxxxxxx1000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 7 - 1 : VERTEX_BRAM_DWIDTH * 6];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxxxxxx10000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 8 - 1 : VERTEX_BRAM_DWIDTH * 7];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxxxxx100000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 9 - 1 : VERTEX_BRAM_DWIDTH * 8];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxxxx1000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 10 - 1 : VERTEX_BRAM_DWIDTH * 9];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxxx10000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 11 - 1 : VERTEX_BRAM_DWIDTH * 10];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxxx100000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 12 - 1 : VERTEX_BRAM_DWIDTH * 11];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxxx1000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 13 - 1 : VERTEX_BRAM_DWIDTH * 12];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxxx10000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 14 - 1 : VERTEX_BRAM_DWIDTH * 13];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxxx100000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 15 - 1 : VERTEX_BRAM_DWIDTH * 14];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxxx1000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 16 - 1 : VERTEX_BRAM_DWIDTH * 15];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxxx10000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 17 - 1 : VERTEX_BRAM_DWIDTH * 16];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxxx100000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 18 - 1 : VERTEX_BRAM_DWIDTH * 17];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxxx1000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 19 - 1 : VERTEX_BRAM_DWIDTH * 18];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxxx10000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 20 - 1 : VERTEX_BRAM_DWIDTH * 19];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxxx100000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 21 - 1 : VERTEX_BRAM_DWIDTH * 20];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxxx1000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 22 - 1 : VERTEX_BRAM_DWIDTH * 21];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxxx10000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 23 - 1 : VERTEX_BRAM_DWIDTH * 22];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxxx100000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 24 - 1 : VERTEX_BRAM_DWIDTH * 23];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxxx1000000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 25 - 1 : VERTEX_BRAM_DWIDTH * 24];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxxx10000000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 26 - 1 : VERTEX_BRAM_DWIDTH * 25];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxxx100000000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 27 - 1 : VERTEX_BRAM_DWIDTH * 26];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxxx1000000000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 28 - 1 : VERTEX_BRAM_DWIDTH * 27];
                    src_p_valid_single <= 1'b1;
                end
                32'bxxx10000000000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 29 - 1 : VERTEX_BRAM_DWIDTH * 28];
                    src_p_valid_single <= 1'b1;
                end
                32'bxx100000000000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 30 - 1 : VERTEX_BRAM_DWIDTH * 29];
                    src_p_valid_single <= 1'b1;
                end
                32'bx1000000000000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 31 - 1 : VERTEX_BRAM_DWIDTH * 30];
                    src_p_valid_single <= 1'b1;
                end
                32'b10000000000000000000000000000000: begin
                    src_p_single <= front_src_p_single[VERTEX_BRAM_DWIDTH * 32 - 1 : VERTEX_BRAM_DWIDTH * 31];
                    src_p_valid_single <= 1'b1;
                end
            endcase
        end
    end

endmodule

module rd_src_p_reorder_block_1_mask #(parameter
    TOT_EDGE_MASK_WIDTH = `TOT_EDGE_MASK_WIDTH, TOT_ACC_ID_WIDTH = `TOT_ACC_ID_WIDTH
    ) (
        input                                   clk,
        input                                   rst,
        input [TOT_EDGE_MASK_WIDTH - 1 : 0]     front_tot_src_p_mask,
        input [TOT_ACC_ID_WIDTH - 1 : 0]        front_tot_acc_id,
        input                                   front_any_dst_data_valid,
        input                                   back_stage_vertex_full,

        output                                  buffer_empty,
        output                                  buffer_full,
        output [TOT_EDGE_MASK_WIDTH - 1 : 0]    tot_src_p_mask,
        output [TOT_ACC_ID_WIDTH - 1 : 0]       tot_acc_id);

    tot_edge_mask_fifo TEM1 (
        .clk(clk), .srst(rst),
        .din(front_tot_src_p_mask), .wr_en(front_any_dst_data_valid), .rd_en(!back_stage_vertex_full),

        .dout(tot_src_p_mask), .empty(buffer_empty), .prog_full(buffer_full));

    tot_acc_id_fifo TAI1 (
        .clk(clk), .srst(rst),
        .din(front_tot_acc_id), .wr_en(front_any_dst_data_valid), .rd_en(!back_stage_vertex_full),

        .dout(tot_acc_id));

endmodule

module rd_src_p_reorder_block_1_vertex_single #(parameter
    DST_ID_DWIDTH = `DST_ID_DWIDTH, VERTEX_MASK_WIDTH = `VERTEX_MASK_WIDTH
    ) (
        input                               clk,
        input                               rst,
        input [DST_ID_DWIDTH - 1 : 0]       front_dst_id,
        input [VERTEX_MASK_WIDTH - 1 : 0]   front_src_p_mask_r,
        input                               front_dst_data_valid,
        input                               front_any_dst_data_valid,
        input                               back_stage_vertex_full,

        output                              buffer_empty,
        output                              buffer_full,
        output                              data_valid,
        output [DST_ID_DWIDTH - 1 : 0]      dst_id,
        output [VERTEX_MASK_WIDTH - 1 : 0]  src_p_mask_r,
        output                              dst_data_valid);

    dst_id_fifo DI1 (
        .clk(clk), .srst(rst),
        .din(front_dst_id), .wr_en(front_any_dst_data_valid), .rd_en(!back_stage_vertex_full),

        .dout(dst_id), .empty(buffer_empty), .prog_full(buffer_full));

    vertex_mask_fifo VM1 (
        .clk(clk), .srst(rst),
        .din(front_src_p_mask_r), .wr_en(front_any_dst_data_valid), .rd_en(!back_stage_vertex_full),
        
        .dout(src_p_mask_r));

    valid_fifo DDV1 (
        .clk(clk), .srst(rst),
        .din(front_dst_data_valid), .wr_en(front_any_dst_data_valid), .rd_en(!back_stage_vertex_full),
        
        .dout(dst_data_valid), .valid(data_valid));

endmodule